package com.geekbang.work.stock;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author nhsoft.lul
 */
@Component
public class RedisUtil {

    @Autowired
    private RedisTemplate redisTemplate;

    private final String STOCK_KEY = "STOCK";

    private String getLua(){
        StringBuilder sb = new StringBuilder();
        sb.append("if (redis.call('exists', KEYS[1]) == 1) then");
        sb.append("    local stock = tonumber(redis.call('get', KEYS[1]));");
        sb.append("    local num = tonumber(ARGV[1]);");
        sb.append("    if (stock < num) then");
        sb.append("        return -1;");
        sb.append("    end;");
        sb.append("    if (stock >= num) then");
        sb.append("        return redis.call('incrby', KEYS[1], 0 - num);");
        sb.append("    end;");
        sb.append("    return -1;");
        sb.append("end;");
        sb.append("return -1;");
        return sb.toString();
    }

    public void setStock(Long stock){
        redisTemplate.opsForValue().set(STOCK_KEY, stock);
    }

    public void reduceByEval(Long num){
        String luaScript = getLua();
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript, Long.class);

        Long evalRes = (Long)redisTemplate.execute(redisScript, Arrays.asList(STOCK_KEY), num.toString());
        if(evalRes != -1){
            System.out.println("库存扣减成功:" + evalRes);
        }else{
            System.out.println("库存不足");
        }
    }

    public void reduce(Long num){
        long stock = Long.parseLong(redisTemplate.opsForValue().get(STOCK_KEY).toString());
        if(stock >= num){
            Long aLong = redisTemplate.opsForValue().decrement(STOCK_KEY, num);
            System.out.println("库存扣减成功:" + aLong);
        }else{
            System.out.println("库存不足");
        }
    }
}
